<?php

namespace wangdian\base;

use wangdian\exception\InvalidConfigException;
use wangdian\exception\InvalidFileSystemException;
use wangdian\exception\InvalidResponseException;
use wangdian\tool\WDTTools;

class BaseApi
{
    protected $instanceDebug = false;
    /**
     * 当前微信配置
     *
     * @var DataArray
     */
    public $config;

    /**
     * BaseApi constructor.
     *
     * @param array $options
     * @param bool  $debug
     * @throws InvalidConfigException
     */
    public function __construct($options, $debug = false)
    {
        if (empty($options['sid'])) {
            throw new InvalidConfigException("Missing Config -- [sid]");
        }
        if (empty($options['appkey'])) {
            throw new InvalidConfigException("Missing Config -- [appkey]");
        }
        if (empty($options['appsecret'])) {
            throw new InvalidConfigException("Missing Config -- [appsecret]");
        }
        $this->instanceDebug = $debug;
        $this->config = new DataArray($options);
    }

    /**
     * 静态创建对象
     *
     * @param array $options
     * @param bool  $debug
     * @return static
     * @throws InvalidConfigException
     */
    public static function instance($options, $debug = false)
    {
        return new static($options, $debug);
    }

    /**
     * 以GET获取接口数据并转为数组
     *
     * @param string $url 接口地址
     * @return array
     * @throws InvalidConfigException
     * @throws InvalidResponseException
     * @throws InvalidFileSystemException
     */
    protected function httpGetForJson($url)
    {
        $tmp = parse_url($url);
        $query = WDTTools::convertUrlQuery($tmp['query']);
        $query['sid'] = $this->config->get('sid');
        $query['appkey'] = $this->config->get('appkey');
        $query['appsecret'] = $this->config->get('appsecret');
        $query['timestamp'] = time();
        $query['sign'] = $this->sign($query);
        $url = WDTTools::removeQueryStringFromUrl($url);
        return WDTTools::json2arr(WDTTools::get($url, $query));
    }

    /**
     * 以POST获取接口数据并转为数组
     *
     * @param string $url  接口地址
     * @param array  $data 请求数据
     * @param bool   $buildToJson
     * @return array
     * @throws InvalidConfigException
     * @throws InvalidResponseException
     * @throws InvalidFileSystemException
     */
    protected function httpPostForJson($url, array $data, $buildToJson = false)
    {
        $options = [];
        if ($buildToJson) {
            $options['headers'] = ['Content-Type: application/json'];
        }
        $data['sid'] = $this->config->get('sid');
        $data['appkey'] = $this->config->get('appkey');
        $data['appsecret'] = $this->config->get('appsecret');
        $data['timestamp'] = time();
        $data['sign'] = $this->sign($data);
        return WDTTools::json2arr(WDTTools::post($url, $buildToJson ? WDTTools::arr2json($data) : $data, $options));
    }

    /**
     * 接口通用POST请求方法
     *
     * @param string $url  接口URL
     * @param array  $data POST提交接口参数
     * @param bool   $isBuildJson
     * @return array
     * @throws InvalidConfigException
     * @throws InvalidResponseException
     * @throws InvalidFileSystemException
     */
    public function callPostApi($url, array $data, $isBuildJson = true)
    {
        return $this->httpPostForJson($url, $data, $isBuildJson);
    }

    /**
     * 接口通用GET请求方法
     *
     * @param string $url 接口URL
     * @return array
     * @throws InvalidConfigException
     * @throws InvalidResponseException
     * @throws InvalidFileSystemException
     */
    public function callGetApi($url)
    {
        return $this->httpGetForJson($url);
    }

    /**
     * @param $options
     * @return string
     * @throws InvalidConfigException
     */
    public function sign(&$options)
    {
        return WDTTools::sign($options);
    }
}
